<?php

namespace App\Http\Controllers\System;

use App\Models\Role;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\Http\Requests\Role\StoreRoleResource;
use App\Http\Requests\Role\UpdateRoleResource;
use App\Http\Requests\Role\QueryRoleCollection;
use App\Http\Requests\Role\DestroyRoleResource;

/**
 * Date: 2018/1/28
 * @author George
 * @package App\Http\Controllers\System
 */
class RoleController extends Controller
{
    /**
     * 获取素有角色信息
     *
     * Date: 2018/1/26
     * @author George
	 * @param QueryRoleCollection $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(QueryRoleCollection $request)
    {
        $roles = Role::with('users')->select(['code', 'name'])->get();
        return $this->success($roles);
    }

    /**
     * 获取指定的角色信息
     *
     * Date: 2018/1/26
     * @author George
     * @param Role $role
     * @return \Illuminate\Http\JsonResponse
     */
    public function show(Role $role)
    {
        return $this->success($role);
    }

    /**
     * 创建角色
     *
     * Date: 2018/1/26
     * @author George
     * @param StoreRoleResource $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Throwable
     */
    public function store(StoreRoleResource $request)
    {
        $attributes = $this->validate($request, [
            'code' => 'required|unique:roles',
            'name' => 'required'
        ], [
        	'code.required' => '角色编码必填',
        	'code.unique' => '角色编码已存在',
        	'name.required' => '角色名称必填'
		]);

        $role = $this->serialization($attributes);
        $role->saveOrFail();
        return $this->stored($role);
    }

    /**
     * 更新角色属性
     *
     * Date: 2018/1/26
     * @author George
     * @param UpdateRoleResource $request
     * @param Role $role
     * @return \Illuminate\Http\JsonResponse
     * @throws \Throwable
     */
    public function update(UpdateRoleResource $request, Role $role)
    {
        $attributes = $this->validate($request, [
			'code' => [
				'required',
				//如果编码未发生改变则忽略
				Rule::unique('roles')->ignore($role->code, 'code'),
			],
            'name' => 'required'
        ]);

        foreach ($attributes as $key => $value) {
            $role->{$key} = $value;
        }

        $role->saveOrFail();
        return $this->updated($role);
    }

    /**
     * 删除角色
     *
     * Date: 2018/1/26
     * @author George
     * @param DestroyRoleResource $request
     * @param Role $role
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function destroy(DestroyRoleResource $request, Role $role)
    {
		//移除角色关联的所有权限
		$role->permissions()->detach();

		//移除角色关联的所有用户
		$role->users()->detach();

		if ($role->delete()) {
			return $this->deleted();
		}
		return $this->failed('删除失败');
    }

    /**
     * 序列化属性为模型
     *
     * Date: 2018/1/26
     * @author George
     * @param array $attributes
     * @return Role
     */
    private function serialization(array $attributes): Role
    {
        $role = new Role();

        foreach ($attributes as $key => $value) {
            $role->{$key} = $value;
        }

        return $role;
    }

	/**
	 * 获取角色关联的权限
	 *
	 * Date: 2018/2/27
	 * @author George
	 * @param Role $role
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function getRolePermission(Role $role)
	{
		$permissions = $role->permissions()->pluck('code');
		return $this->success($permissions);
    }

	/**
	 * 更新角色权限
	 *
	 * Date: 2018/2/27
	 * @author George
	 * @param Request $request
	 * @param Role $role
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function syncRolePermission(Request $request, Role $role)
	{
		$params = $this->validate($request, [
			'relations' => 'required'
		]);
		$role->permissions()->sync($params['relations']);
		return $this->updated($params['relations']);
    }
}
